﻿using BackEnd;
using Microsoft.Win32;
using System;
using System.Data;
using System.IO;
using System.Windows;
using System.Windows.Input;

namespace FrontEnd
{
	public partial class MainWindow : Window
	{
		#region CONSTRUCTOR(S)
		public MainWindow()
		{
			InitializeComponent();

			_dbMgr = new SQLiteManager();
			_dbMgr.Connected += Connected;
			_dbMgr.Disconnected += Disconnected;
			_dbMgr.Attached += Attached;
			_dbMgr.Detached += Detached;
			_dbMgr.Result += ResultsReturned;
			_dbMgr.Error += Error;

			// hook up object explorer
			objExplorer.Refreshing += Refreshing;
			objExplorer.Request += Requested;
			objExplorer.Attaching += Attaching;
			objExplorer.Detaching += Detaching;
			objExplorer.Connecting += Connecting;
		}
		#endregion

		#region PRIVATE METHODS

		private void Create(object sender, ExecutedRoutedEventArgs e)
		{
			var dlg = new SaveFileDialog();
			dlg.FileName = "newdb";
			dlg.DefaultExt = ".db3";
			dlg.Filter = "SQLite Database (*.db3)|*.db3";

			var result = dlg.ShowDialog();
			if (result == true)
			{
				string filePath = dlg.FileName;
				_dbMgr.Create(filePath);
			}
		}

		private void Exit(object sender, ExecutedRoutedEventArgs e)
		{
			Application.Current.Shutdown();
		}

		private void Requested(object sender, dynamic request)
		{
			_dbMgr.HandleRequest(request);
		}

		private void Refreshing(object sender, EventArgs e)
		{
			RefreshObjectExplorer();
		}

		private void Connecting(object sender, string filePath)
		{
			_dbMgr.Connect(filePath);
		}

		private void Connected(object sender, Database db)
		{
			RefreshObjectExplorer();

			// initial blank tab
			AddNewTab();
		}

		private void Disconnected(object sender, EventArgs e)
		{
			RefreshObjectExplorer();
		}

		private void Attaching(object sender, string filePath)
		{
			_dbMgr.Attach(filePath);
		}

		private void Attached(object sender, Database db)
		{
			RefreshObjectExplorer();
		}

		private void Detaching(object sender, string dbName)
		{
			_dbMgr.Detach(dbName);
		}

		private void Detached(object sender, string dbName)
		{
			RefreshObjectExplorer();
		}

		private void ResultsReturned(object sender, Result result)
		{
			if (result is VectorResult)
			{
				// if query originated from a tab send result back
				//  there else create new tab
				if (result.Request.Source is SQLQueryTab)
				{
					var origTab = result.Request.Source as SQLQueryTab;
					origTab.AssignResult(result);
				}
				else
				{
					AddNewTab(initResult: result);
				}
			}
			else if (result is ScriptResult)
			{
				AddNewTab(initResult: result);
			}
			else if(result is ScalarResult)
			{
				var res = result as ScalarResult;
				MessageBox.Show(res.Value.ToString(), "SQLiter", MessageBoxButton.OK, MessageBoxImage.Information);
			}
		}

		private void CanCreateNewTab(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = _dbMgr.MainDatabase != null;
		}

		private void NewTab(object sender, ExecutedRoutedEventArgs e)
		{
			AddNewTab();
		}

		private SQLQueryTab AddNewTab(string title = null, bool isFocused = true, Result initResult = null)
		{
			var tab = new SQLQueryTab();
			tab.Request += Requested;
			tabQueryWindows.Items.Add(tab);

			// set title
			if (string.IsNullOrEmpty(title))
				tab.Title = string.Format("query{0}.sql", tabQueryWindows.Items.Count);
			else
				tab.Title = title;

			// initial result
			if(initResult != null)
				tab.AssignResult(initResult);

			// focus
			if (isFocused)
			{
				tabQueryWindows.SelectedIndex = tabQueryWindows.Items.Count - 1;
				// TODO: also set the focus in the edit box, pref. at the end
			}	
			
			return tab;
		}

		private void RefreshObjectExplorer()
		{
			objExplorer.Populate(_dbMgr.Databases);
		}

		private void Error(object sender, ErrorEventArgs e)
		{
			var errMsg = e.GetException().Message;
			MessageBox.Show(this, errMsg, "SQLiter", MessageBoxButton.OK, MessageBoxImage.Error);
		}

		#endregion

		#region PRIVATE MEMBERS
		private SQLiteManager _dbMgr;
		#endregion
	}
}
